<template>
  <view
    v-if="!unmount || visible"
    v-show="visible"
    :class="className"
    :style="style"
    @click="handleClick"
  >
    <slot></slot>
  </view>
</template>

<script lang="ts">
import { computed, CSSProperties, onMounted, ref, watch } from "vue";

export const requestAnimationFrame = (cb = () => {}) => {
  let timer = null;
  return (timer = setInterval(() => {
    clearInterval(timer);
    cb();
  }, 1000 / 30));
};

export default {
  name: "Transition",
  options: {
    // 虚拟化节点
    virtualHost: true,
  },
  props: {
    name: {
      type: String,
      default: "fade",
    },
    // 动画的flog
    show: {
      type: Boolean,
      default: false,
    },
    animation: {
      type: Boolean,
      default: false,
    },
    /**
     * 是否对初始渲染使用过渡。
     * 默认：false
     */
    appear: {
      type: Boolean,
      default: false,
    },
    // 是否使用v-if
    unmount: {
      type: Boolean,
      default: false,
    },
    mode: {
      type: String,
      default: "",
    },
    css: {
      type: Boolean,
      default: true,
    },
    customClass: {
      type: String,
      default: "",
    },
    duration: {
      type: Number,
      default: 1000,
    },
  },
  emits: ["after-enter", "after-leave", "click"],
  setup(props, { emit }) {
    const prefixCls = "arco-transition";
    const innerClass = ref([]);

    const visible = ref(false);

    let timerId = null;

    const transitionClassName = computed(() => {
      //进入动画
      const enter = [`${props.name}-enter-from`]; //进入动画
      const enterto = [`${props.name}-enter-active`, `${props.name}-enter-to`]; //离开动画

      const leave = [`${props.name}-leave-from`]; //离开动画
      const leaveto = [`${props.name}-leave-active`, `${props.name}-leave-to`];

      return {
        enter,
        enterto,
        leave,
        leaveto,
      };
    });

    watch(
      () => props.show,
      (values) => {
        handleShow(values);
      },
    );

    function handleShow(value) {
      if (value) {
        clear();
        enters();
      } else {
        leaves();
      }
    }

    function clear() {
      if (timerId) {
        clearInterval(timerId);
      }
    }

    onMounted(() => {
      if (props.appear && props.show) {
        enters();
      } else {
        visible.value = props.show;
      }
    });

    // enters();

    function leaves() {
      const { leave, leaveto } = transitionClassName.value;
      innerClass.value = leave;
      setTimeout(() => {
        innerClass.value = leaveto;
      }, 30);
      clear();
      timerId = setTimeout(() => {
        visible.value = false;
        timerId = null;
        emit("after-leave");
      }, props.duration);
    }

    function enters() {
      //   const ds = requestAnimationFrame();
      const { enter, enterto } = transitionClassName.value;
      innerClass.value = enter;
      visible.value = true;
      setTimeout(() => {
        innerClass.value = enterto;
      }, 30);
      clear();
      timerId = setTimeout(() => {
        // 等待动画完成修改 innerShow
        innerClass.value = [];
        // this.__timerId = null;
        timerId = null;
      }, props.duration);
    }

    function handleClick() {
      emit("click");
    }

    const style = computed<CSSProperties>(() => {
      const styesNode: CSSProperties = {};
      if (props.animation) {
        styesNode["animation-duration"] = `${props.duration}ms`;
      } else {
        styesNode["transition-duration"] = `${props.duration}ms`;
      }
      return styesNode;
    });

    const className = computed(() => {
      // 处理 innerClass.value 的边界条件
      const classArray = Array.isArray(innerClass.value)
        ? innerClass.value
        : [innerClass.value || ""];
      // 确保类名之间有适当的空格分隔
      const classString = classArray.filter(Boolean).join(" ");
      return `${prefixCls}  ${classString}`;
    });

    return {
      className,
      innerClass,
      style,
      leaves,
      enters,
      visible,
      handleClick,
    };
  },
};
</script>
